package com.example.base.security.jwt;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.base.security.SecurityUtil;
import com.example.base.security.SysUser;
import com.example.base.security.SysUserType;
import com.example.base.security.domain.SelfUserEntity;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/6/11 15:04
 * @since JDK 1.8
 */
@Slf4j
public class JWTTokenUtil {
    /**
     * 私有化构造器
     */
    private JWTTokenUtil(){}

    /**
     * 生成Token
     * @Author Sans
     * @CreateTime 2019/10/2 12:16
     * @Param  selfUserEntity 用户安全实体
     * @Return Token
     */
    public static String createAccessToken(SelfUserEntity selfUserEntity){
        // 登陆成功生成JWT
        String token = Jwts.builder()
                // 放入用户名和用户ID
                .setId(selfUserEntity.getUserId()+"")
                // 主题
                .setSubject(selfUserEntity.getUsername())
                // 签发时间
                .setIssuedAt(new Date())
                // 签发者
                .setIssuer("sans")
                // 自定义属性 放入用户拥有权限
                .claim("authorities", JSON.toJSONString(selfUserEntity.getAuthorities()))
                // 失效时间
                .setExpiration(new Date(System.currentTimeMillis() + JWTConfig.expiration))
                // 签名算法和密钥
                .signWith(SignatureAlgorithm.HS512, JWTConfig.secret)
                .compact();

        log.info("token："+token);
        return token;
    }


    public static Claims getClaimsByToken(String token){
        try {
            token = token.replace(JWTConfig.tokenPrefix, "");
            Claims claims = Jwts.parser()
                    .setSigningKey(JWTConfig.secret)
                    .parseClaimsJws(token)
                    .getBody();
            return claims;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    public static void tokenPass(String token, Claims claims, HttpServletResponse response){
        String userId=claims.getId();
        String username = claims.getSubject();
        log.info("username:{}",username);
        if(!StringUtils.isEmpty(username)&&!StringUtils.isEmpty(userId)) {
            // 获取角色
            List<GrantedAuthority> authorities = new ArrayList<>();
            String authority = claims.get("authorities").toString();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(authority) && !"null".equals(authority)){
                List<Map<String,String>> authorityMap = JSONObject.parseObject(authority, List.class);
                for(Map<String,String> role : authorityMap){
                    if(!StringUtils.isEmpty(role)) {
                        authorities.add(new SimpleGrantedAuthority(role.get("authority")));
                    }
                }
            }
            //组装参数
            SelfUserEntity selfUserEntity = new SelfUserEntity();
            selfUserEntity.setUsername(claims.getSubject());
            selfUserEntity.setUserId(Integer.parseInt(claims.getId()));
            selfUserEntity.setAuthorities(authorities);

            //如果设置此项失败，则将不允许登录
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(selfUserEntity, userId, authorities);
            SecurityContextHolder.getContext().setAuthentication(authentication);

            SysUser sysUser=new SysUser();
            sysUser.setUserId(String.valueOf(selfUserEntity.getUserId()));
            sysUser.setUserName(selfUserEntity.getUsername());
            sysUser.setDeptId(selfUserEntity.getDeptId());
            sysUser.setRoleId(selfUserEntity.getRoleId());
            sysUser.setUserType(SysUserType.SYSTEM.getUserType());
            SecurityUtil.setSysUserEntity(sysUser);
            Cookie cookie = new Cookie(JWTConfig.tokenHeader, token);

            // 设置Cookie的其他属性（可选）
            cookie.setMaxAge(3600); // 设置Cookie的生命周期，单位为秒
            cookie.setPath("/"); // 设置Cookie的路径
            // 其他属性，如：cookie.setDomain("domain.com");
            // 将Cookie添加到响应中
            response.addCookie(cookie);
        }
    }



}
